package com.dcy.znoa.common.util.excel;

import com.dcy.znoa.common.util.DateTimeUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by xialin on 2017/5/6.
 * excel 操作类
 *
 * @param <T>
 */
public class ExcelUtilXialin<T> extends IoExcel {

    /**
     * 将 excel 读取转换为 List
     * 只会读取第一个工作薄
     *
     * @param t      实体
     * @param stream 数据流
     * @param isXlsx 文件类型
     * @return 返回  list
     */
    public List<T> excelToList(T t, InputStream stream, boolean isXlsx) {
        try {
            //验证是否为空且不能为空字节
            if (stream == null) {
                this.errorMessage = "excel 文件没有数据";
                return new ArrayList<T>();
            }
            Workbook workbook;
            if (isXlsx) {
                workbook = new XSSFWorkbook(stream);
            } else {
                workbook = new HSSFWorkbook(stream);
            }

            //工作簿
            Sheet sheet = workbook.getSheetAt(0);
            //返回执行结果
            return readExcelToList(t, sheet);
        } catch (IOException ex) {
            this.errorMessage = ex.getMessage();
            return new ArrayList<T>();
        }
    }

    /**
     * 将 list 转换为 excel
     * 可能会分工作薄
     *
     * @param list     泛型数据
     * @param filePath 文件路径
     * @param fileName 文件名
     * @return 返回 String 文件下载路径
     */
    public String listToExcel(List<T> list, String filePath, String fileName) {
        if (list == null || list.size() == 0) {
            this.errorMessage = "没有可转换的数据";
            return "";
        }

        //文件路径
        if (filePath == null || filePath.isEmpty()) {
            this.errorMessage = "保存路径不能为空！";
            return "";
        }

        //删除两天以前的 excel 文件
        deleteFile(filePath, new String[]{".xlsx", ".xls"}, 2);

        String sheetName = "";
        //文件名
        String timeString = DateTimeUtil.geSpecifiedFormatTime("yyyyMMddHHmmss");

        if (fileName.isEmpty()) {
            fileName = "自动生成文件名" + timeString;
        } else {
            fileName = fileName.toLowerCase();
            String suffix = ".xlsx";
            if (!fileName.endsWith(".xlsx"))
                suffix = ".xls";

            sheetName = fileName.replace(suffix, "");
            fileName = sheetName + timeString + suffix;
        }


        // xlsx 每个工作工作薄最大行常量
        long totalRow = 1048576;
        int size = list.size();
        long sheetNum = size / totalRow;
        if (size % totalRow > 0)
            sheetNum += 1;
        FileOutputStream fileOut =null;
        try {
            Workbook workbook = new XSSFWorkbook();
            //创建文件
            readListToExcel(list, workbook, sheetName, sheetNum, totalRow);

            //将流输入到文件输出流
            fileOut = new FileOutputStream(filePath + fileName);
            workbook.write(fileOut);
            //处理内存
            fileOut.flush();
            fileOut.close();

        } catch (IOException ex) {
            this.errorMessage = ex.getMessage();
            ex.printStackTrace();
            return "";
        }finally {
            try {
                if(fileOut != null) {
                    fileOut.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


        //返回最终文件名
        return fileName;
    }

    /**
     * 删除指定类型文件
     * 只删除
     *
     * @param filePath 指定目录
     * @param suffix   要删除的文件后缀
     * @param day      当前时间之前多久
     * @return boolean
     */
    public boolean deleteFile(String filePath, String[] suffix, Integer day) {
        if (suffix == null)
            suffix = new String[]{};
        List<String> suffixList = Arrays.stream(suffix).collect(Collectors.toList());

        //获取时间
        Date currentTime = new Date();
        Calendar date = Calendar.getInstance();
        date.setTime(currentTime);
        date.set(Calendar.DATE, date.get(Calendar.DATE) - day);
        Long dateTime = date.getTime().getTime();

        File file = new File(filePath);
        String[] tempList = file.list();
        if (tempList == null)
            return true;
        try {
            Arrays.stream(tempList)
                    .forEach(fileName -> {
                        //获取文件名称后缀
                        String prefix = fileName.substring(fileName.lastIndexOf(".") + 1);
                        if (suffixList.size() == 0 || suffixList.contains(prefix)) {
                            File temp = new File(fileName);
                            Long time = temp.lastModified();
                            if (time < dateTime)
                                temp.delete();
                        }
                    });
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
    }
}
